package com.hmdp.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMQConfig {

    // 正常业务队列和交换机的定义 -------------------------------------------------
    /**
     * 增加消费者并发数
     */
    @Bean
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setConcurrentConsumers(5);
        factory.setMaxConcurrentConsumers(10);
        factory.setMessageConverter(jsonMessageConverter());
        factory.setChannelTransacted(false); // 改为false，因为我们使用手动ack
        factory.setPrefetchCount(1);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); // 显式设置手动确认模式
        return factory;
    }

    /** 正常订单交换机 */
    @Bean
    public TopicExchange orderTopicExchange() {
        return new TopicExchange("order.topic", true, false); // 持久化，不自动删除
    }

    /** 正常订单队列（绑定死信交换器） */
    @Bean
    public Queue orderQueue() {
        return QueueBuilder.durable("order.seckill.queue") // 队列名称
                .withArgument("x-dead-letter-exchange", "dlx.exchange") // 死信交换机
                .withArgument("x-dead-letter-routing-key", "order.dead") // 死信路由键
                .withArgument("x-message-ttl", 1800000) // 可选：消息30分钟未处理则进入死信队列
                .build();
    }

    /** 绑定正常队列到交换机 */
    @Bean
    public Binding orderBinding() {
        return BindingBuilder.bind(orderQueue())
                .to(orderTopicExchange())
                .with("SeckillVoucher"); // 路由键匹配生产者发送时使用的key
    }

    // 死信队列和交换机的定义 -------------------------------------------------

    /** 死信交换机 */
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange("dlx.exchange", true, false); // 持久化
    }

    /** 死信队列 */
    /** （增加延迟功能） */
    @Bean
    public Queue dlxQueue() {
        return QueueBuilder.durable("dlx.queue")
                .withArgument("x-dead-letter-exchange", "order.topic") // 过期后回到主交换机
                .withArgument("x-dead-letter-routing-key", "SeckillVoucher")
                .withArgument("x-message-ttl", 60000) // 60秒延迟（测试验证）
                .build();
    }

    /** 绑定死信队列到死信交换机 */
    @Bean
    public Binding dlxBinding() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with("order.dead"); // 路由键需与正常队列的x-dead-letter-routing-key一致
    }

    // 其他配置（如消息转换器）-------------------------------------------------
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}